# load("./data/Robjects/Annotated_Results_LvV.RData")
# load("./data/Robjects/Ensembl_annotations.RData")
# load("./data/Robjects/DE.RData")
# load("./data/Robjects/01_DDS.RData")
# load("./data/Robjects/02_annot.RData")
load("./data/Robjects/03_DDS.RData")

select genes to analyse

for now only using the gastroc tissue

# res_sorted <- data.frame(res.gastroc, stringsAsFactors = F) %>%
#   na.omit() %>%
#   subset(., (log2FoldChange >= 1 |
#                log2FoldChange <= -1)) %>% # set arbitrarily
#   arrange(desc(abs(log2FoldChange))) # order by fold change (absolute value)
# # up-regulated genes
# up <- na.omit(res_sorted) %>%
#   subset(.,  log2FoldChange > 0 & padj < 0.01)
res_sorted<-data.frame(gene = rownames(res.gastroc),res.gastroc,stringsAsFactors = F)%>%
  na.omit()%>%
  subset(., ( log2FoldChange >=1 | log2FoldChange <=-1))%>% # set abritarily
  arrange(desc( abs(log2FoldChange) )) # order by fold change (absolute value)
# up-regulated genes
up<-data.frame(rn= rownames(res_sorted),res_sorted) %>%
  na.omit()%>%
  subset(., log2FoldChange > 0 & padj < 0.05)
gp_up <- gost(row.names(up), organism = "mmusculus", evcodes = TRUE, ordered_query = TRUE,
            correction_method = "gSCS", user_threshold = 0.01, 
            sources = c("GO:BP", "GO:MF", "GO:CC", "KEGG", "REAC", "TF", "MIRNA", "CORUM", "HP", "HPA", "WP")) # ordered by foldchange; evcodes generates gene names (makes run time longer though)

Result visualization

require(enrichplot)
require(ggplot2)
require(viridis)
require(shiny)
require(DOSE)

div(gostplot(gp_up, interactive = TRUE), align = "right") # interactive plot; circle sizes are in accordance with corresponding term size; term location on the x-axis is fixed and terms from the same GO subtree are located closer to each other

# define as enrichResult object and plot
gp_up_df<-gp_up$result[,c("query", "source", "term_id", "term_name",
                          "p_value", "query_size", "intersection_size",
                          "term_size", "effective_domain_size", "intersection")]%>%
  mutate(intersection = gsub(",", "/", intersection),
         GeneRatio = paste0(intersection_size, "/", query_size),
         BgRatio = paste0(term_size, "/", effective_domain_size))
names(gp_up_df) = c("Cluster", "Category", "ID", "Description", "p.adjust",
"query_size", "Count", "term_size", "effective_domain_size", "geneID", "GeneRatio", "BgRatio")
row.names(gp_up_df) = gp_up_df$ID
#gp_up_df<-subset(gp_up_df, Category == "REAC") # can prefilter for databases of interest

# dotplot
enrichplot::dotplot(new("enrichResult", result = gp_up_df))+
  theme_minimal()+
  scale_color_viridis()+
  theme(axis.title=element_text(size=rel(1.5), colour = "black"),
        axis.line=element_line(colour = "grey40"),
        panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        axis.ticks.x=(element_line(size=0.5, colour = "grey40")))

# barplot
 barplot(new("enrichResult", result = gp_up_df), showCategory = 10)+
   ggplot2::facet_grid(~Cluster) +
   ggplot2::ylab("Intersection size")+
   theme_minimal()+
   scale_fill_viridis()+
   theme(axis.title=element_text(size=rel(1.5), colour = "black"),
        axis.line=element_line(colour = "grey40"),
        panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        axis.ticks.x=(element_line(size=0.5, colour = "grey40")))

# terms and gene names
enrichplot::heatplot(new("enrichResult", result = gp_up_df), showCategory = 10) +
  theme_minimal() +
  theme(
    axis.title = element_text(size = rel(1.5), colour = "black"),
    axis.text.x = element_text(angle = 90),
    axis.line = element_line(colour = "grey40"),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.ticks.x = (element_line(size = 0.5, colour = "grey40"))
  )

# terms and gene names 2
enrichplot::cnetplot(
  new("enrichResult", result = gp_up_df),
  showCategory = 3,
  cex_label_gene = 0.5
) +
  scale_colour_manual(values = c("grey70", "black"), guide = FALSE)

# terms and gene names 3
enrichplot::cnetplot(
  new("enrichResult", result = gp_up_df),
  showCategory = 3,
  circular = TRUE,
  colorEdge = TRUE,
  cex_label_gene = 0.5
)

topGO

library(topGO)
library(org.Hs.eg.db)
# named vector of up-regulated genes
temp <- data.frame(rn = rownames(res_sorted), res_sorted) %>%
  na.omit() %>%
  mutate(up = ifelse(log2FoldChange > 0, padj, 1)) #set the p-value for down regulations to 1
# make a named vector
res_sorted_up <- temp$up
names(res_sorted_up) <- temp$rn
rm(temp)
# function for enrichment with p 0.05
topDiffGenes <- function(x) {
  return(x < 0.05)
}
### run
tg.up<-new("topGOdata",#just a name
           description="res_sorted_up",
           ontology="BP",
           allGenes=res_sorted_up[1:100], #named vector with adj. p-values
           geneSel=topDiffGenes,
           annot=annFUN.org,
           nodeSize = 10, #minimum number of genes in a GO category
           ID="Ensembl",
           mapping="org.Hs.eg.db")
Error in split.default(names(sort(nl)), f.index) : 
  first argument must be a vector

Reactome

“Reactome is a free, open-source, curated and peer-reviewed pathway database.” ReactomePA is a useful package that allows you to use Reactome database and visualize your results.

Finding significant Reactome pathways from gene list

#Make a data frame with gene names and corresponding ENTREZ IDs.
ensgEntrez_mutant <- AnnotationDbi::select(org.Mm.eg.db, keys=names(mutant_up), columns='ENSEMBLID', keytype='SYMBOL')
Error in .testForValidCols(x, cols) : 
  Invalid columns: ENSEMBLID. Please use the columns method to see a listing of valid arguments.

Visualizing Reactome results with ReactomePA

#You can save the plot as png but set the resolution (widthxheight).

png(file="ReactomeDot_Mutant_Control_Up.png", width=1440, height=1280)
dotplot(x_mutant_up, showCategory=30, font.size=15, label_format = 10) + ggtitle("Mutant vs Control Upregulated") + theme(plot.title = element_text(size = 30, face = "bold"))
dev.off()

#For the next one, we need to add Log2FoldChanges too. Make a named vector just like we did with p-adjusted values before.
lfc <-df_mutant$lfc
names(lfc)<-df_mutant$ENTREZID


#Make and save the plot
png(file="CNET_Mutant_Control_Up.png", width=1440, height=1440)
cnetplot(x_mutant_up, showCategory =10, foldChange=2^lfc,cex_label_gene = 1.2, cex_label_category = 1.8) + ggtitle("Mutant vs Control Upregulated") + theme(plot.title = element_text(size = 40, face = "bold"))
dev.off()
save(gp_up, tg.up, file = "./data/Robjects/05_enrichment.RData")
load("./data/Robjects/05_enrichment.RData")
LS0tCnRpdGxlOiAiMDUgZW5yaWNobWVudCBhbmFseXNpcyIKYXV0aG9yOiAiTmljayBEaWVyY2tzZW4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKbGlicmFyeShkcGx5cikKIyBsaWJyYXJ5KGdncGxvdDIpCiMgbGlicmFyeShmZ3NlYSkKbGlicmFyeShncHJvZmlsZXIyKQpsaWJyYXJ5KERFU2VxMikKYGBgCgoKCmBgYHtyfQojIGxvYWQoIi4vZGF0YS9Sb2JqZWN0cy9Bbm5vdGF0ZWRfUmVzdWx0c19MdlYuUkRhdGEiKQojIGxvYWQoIi4vZGF0YS9Sb2JqZWN0cy9FbnNlbWJsX2Fubm90YXRpb25zLlJEYXRhIikKIyBsb2FkKCIuL2RhdGEvUm9iamVjdHMvREUuUkRhdGEiKQojIGxvYWQoIi4vZGF0YS9Sb2JqZWN0cy8wMV9ERFMuUkRhdGEiKQojIGxvYWQoIi4vZGF0YS9Sb2JqZWN0cy8wMl9hbm5vdC5SRGF0YSIpCmxvYWQoIi4vZGF0YS9Sb2JqZWN0cy8wM19ERFMuUkRhdGEiKQpgYGAKCgojIHNlbGVjdCBnZW5lcyB0byBhbmFseXNlCmZvciBub3cgb25seSB1c2luZyB0aGUgZ2FzdHJvYyB0aXNzdWUKYGBge3J9CiMgcmVzX3NvcnRlZCA8LSBkYXRhLmZyYW1lKHJlcy5nYXN0cm9jLCBzdHJpbmdzQXNGYWN0b3JzID0gRikgJT4lCiMgICBuYS5vbWl0KCkgJT4lCiMgICBzdWJzZXQoLiwgKGxvZzJGb2xkQ2hhbmdlID49IDEgfAojICAgICAgICAgICAgICAgIGxvZzJGb2xkQ2hhbmdlIDw9IC0xKSkgJT4lICMgc2V0IGFyYml0cmFyaWx5CiMgICBhcnJhbmdlKGRlc2MoYWJzKGxvZzJGb2xkQ2hhbmdlKSkpICMgb3JkZXIgYnkgZm9sZCBjaGFuZ2UgKGFic29sdXRlIHZhbHVlKQojICMgdXAtcmVndWxhdGVkIGdlbmVzCiMgdXAgPC0gbmEub21pdChyZXNfc29ydGVkKSAlPiUKIyAgIHN1YnNldCguLCAgbG9nMkZvbGRDaGFuZ2UgPiAwICYgcGFkaiA8IDAuMDEpCnJlc19zb3J0ZWQ8LWRhdGEuZnJhbWUoZ2VuZSA9IHJvd25hbWVzKHJlcy5nYXN0cm9jKSxyZXMuZ2FzdHJvYyxzdHJpbmdzQXNGYWN0b3JzID0gRiklPiUKICBuYS5vbWl0KCklPiUKICBzdWJzZXQoLiwgKCBsb2cyRm9sZENoYW5nZSA+PTEgfCBsb2cyRm9sZENoYW5nZSA8PS0xKSklPiUgIyBzZXQgYWJyaXRhcmlseQogIGFycmFuZ2UoZGVzYyggYWJzKGxvZzJGb2xkQ2hhbmdlKSApKSAjIG9yZGVyIGJ5IGZvbGQgY2hhbmdlIChhYnNvbHV0ZSB2YWx1ZSkKIyB1cC1yZWd1bGF0ZWQgZ2VuZXMKdXA8LWRhdGEuZnJhbWUocm49IHJvd25hbWVzKHJlc19zb3J0ZWQpLHJlc19zb3J0ZWQpICU+JQogIG5hLm9taXQoKSU+JQogIHN1YnNldCguLCBsb2cyRm9sZENoYW5nZSA+IDAgJiBwYWRqIDwgMC4wNSkKCmBgYAoKYGBge3J9CmdwX3VwIDwtIGdvc3Qocm93Lm5hbWVzKHVwKSwgb3JnYW5pc20gPSAibW11c2N1bHVzIiwgZXZjb2RlcyA9IFRSVUUsIG9yZGVyZWRfcXVlcnkgPSBUUlVFLAogICAgICAgICAgICBjb3JyZWN0aW9uX21ldGhvZCA9ICJnU0NTIiwgdXNlcl90aHJlc2hvbGQgPSAwLjAxLCAKICAgICAgICAgICAgc291cmNlcyA9IGMoIkdPOkJQIiwgIkdPOk1GIiwgIkdPOkNDIiwgIktFR0ciLCAiUkVBQyIsICJURiIsICJNSVJOQSIsICJDT1JVTSIsICJIUCIsICJIUEEiLCAiV1AiKSkgIyBvcmRlcmVkIGJ5IGZvbGRjaGFuZ2U7IGV2Y29kZXMgZ2VuZXJhdGVzIGdlbmUgbmFtZXMgKG1ha2VzIHJ1biB0aW1lIGxvbmdlciB0aG91Z2gpCmBgYAoKCiMgUmVzdWx0IHZpc3VhbGl6YXRpb24KCmBgYHtyIGVjaG89VCwgZmlnLmFsaWduPSJjZW50ZXIiLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGVucmljaHBsb3QpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHNoaW55KQpsaWJyYXJ5KERPU0UpCgpkaXYoZ29zdHBsb3QoZ3BfdXAsIGludGVyYWN0aXZlID0gVFJVRSksIGFsaWduID0gInJpZ2h0IikgIyBpbnRlcmFjdGl2ZSBwbG90OyBjaXJjbGUgc2l6ZXMgYXJlIGluIGFjY29yZGFuY2Ugd2l0aCBjb3JyZXNwb25kaW5nIHRlcm0gc2l6ZTsgdGVybSBsb2NhdGlvbiBvbiB0aGUgeC1heGlzIGlzIGZpeGVkIGFuZCB0ZXJtcyBmcm9tIHRoZSBzYW1lIEdPIHN1YnRyZWUgYXJlIGxvY2F0ZWQgY2xvc2VyIHRvIGVhY2ggb3RoZXIKCiMgZGVmaW5lIGFzIGVucmljaFJlc3VsdCBvYmplY3QgYW5kIHBsb3QKZ3BfdXBfZGY8LWdwX3VwJHJlc3VsdFssYygicXVlcnkiLCAic291cmNlIiwgInRlcm1faWQiLCAidGVybV9uYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAicF92YWx1ZSIsICJxdWVyeV9zaXplIiwgImludGVyc2VjdGlvbl9zaXplIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidGVybV9zaXplIiwgImVmZmVjdGl2ZV9kb21haW5fc2l6ZSIsICJpbnRlcnNlY3Rpb24iKV0lPiUKICBtdXRhdGUoaW50ZXJzZWN0aW9uID0gZ3N1YigiLCIsICIvIiwgaW50ZXJzZWN0aW9uKSwKICAgICAgICAgR2VuZVJhdGlvID0gcGFzdGUwKGludGVyc2VjdGlvbl9zaXplLCAiLyIsIHF1ZXJ5X3NpemUpLAogICAgICAgICBCZ1JhdGlvID0gcGFzdGUwKHRlcm1fc2l6ZSwgIi8iLCBlZmZlY3RpdmVfZG9tYWluX3NpemUpKQpuYW1lcyhncF91cF9kZikgPSBjKCJDbHVzdGVyIiwgIkNhdGVnb3J5IiwgIklEIiwgIkRlc2NyaXB0aW9uIiwgInAuYWRqdXN0IiwKInF1ZXJ5X3NpemUiLCAiQ291bnQiLCAidGVybV9zaXplIiwgImVmZmVjdGl2ZV9kb21haW5fc2l6ZSIsICJnZW5lSUQiLCAiR2VuZVJhdGlvIiwgIkJnUmF0aW8iKQpyb3cubmFtZXMoZ3BfdXBfZGYpID0gZ3BfdXBfZGYkSUQKI2dwX3VwX2RmPC1zdWJzZXQoZ3BfdXBfZGYsIENhdGVnb3J5ID09ICJSRUFDIikgIyBjYW4gcHJlZmlsdGVyIGZvciBkYXRhYmFzZXMgb2YgaW50ZXJlc3QKCiMgZG90cGxvdAplbnJpY2hwbG90Ojpkb3RwbG90KG5ldygiZW5yaWNoUmVzdWx0IiwgcmVzdWx0ID0gZ3BfdXBfZGYpKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpKwogIHRoZW1lKGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9cmVsKDEuNSksIGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMubGluZT1lbGVtZW50X2xpbmUoY29sb3VyID0gImdyZXk0MCIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3I9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3I9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD0oZWxlbWVudF9saW5lKHNpemU9MC41LCBjb2xvdXIgPSAiZ3JleTQwIikpKQojIGJhcnBsb3QKIGJhcnBsb3QobmV3KCJlbnJpY2hSZXN1bHQiLCByZXN1bHQgPSBncF91cF9kZiksIHNob3dDYXRlZ29yeSA9IDEwKSsKICAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZCh+Q2x1c3RlcikgKwogICBnZ3Bsb3QyOjp5bGFiKCJJbnRlcnNlY3Rpb24gc2l6ZSIpKwogICB0aGVtZV9taW5pbWFsKCkrCiAgIHNjYWxlX2ZpbGxfdmlyaWRpcygpKwogICB0aGVtZShheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPXJlbCgxLjUpLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5NDAiKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9KGVsZW1lbnRfbGluZShzaXplPTAuNSwgY29sb3VyID0gImdyZXk0MCIpKSkKYGBgCgoKYGBge3IsIGVjaG89VCwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9MTAsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgdGVybXMgYW5kIGdlbmUgbmFtZXMKZW5yaWNocGxvdDo6aGVhdHBsb3QobmV3KCJlbnJpY2hSZXN1bHQiLCByZXN1bHQgPSBncF91cF9kZiksIHNob3dDYXRlZ29yeSA9IDEwKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHJlbCgxLjUpLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLAogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5NDAiKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcy54ID0gKGVsZW1lbnRfbGluZShzaXplID0gMC41LCBjb2xvdXIgPSAiZ3JleTQwIikpCiAgKQojIHRlcm1zIGFuZCBnZW5lIG5hbWVzIDIKZW5yaWNocGxvdDo6Y25ldHBsb3QoCiAgbmV3KCJlbnJpY2hSZXN1bHQiLCByZXN1bHQgPSBncF91cF9kZiksCiAgc2hvd0NhdGVnb3J5ID0gMywKICBjZXhfbGFiZWxfZ2VuZSA9IDAuNQopICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImdyZXk3MCIsICJibGFjayIpLCBndWlkZSA9IEZBTFNFKQojIHRlcm1zIGFuZCBnZW5lIG5hbWVzIDMKZW5yaWNocGxvdDo6Y25ldHBsb3QoCiAgbmV3KCJlbnJpY2hSZXN1bHQiLCByZXN1bHQgPSBncF91cF9kZiksCiAgc2hvd0NhdGVnb3J5ID0gMywKICBjaXJjdWxhciA9IFRSVUUsCiAgY29sb3JFZGdlID0gVFJVRSwKICBjZXhfbGFiZWxfZ2VuZSA9IDAuNQopCgpgYGAKCiMgdG9wR08KCmBgYHtyLCBlY2hvPVQsIGZpZy5hbGlnbj0iY2VudGVyIn0KbGlicmFyeSh0b3BHTykKbGlicmFyeShvcmcuSHMuZWcuZGIpCiMgbmFtZWQgdmVjdG9yIG9mIHVwLXJlZ3VsYXRlZCBnZW5lcwp0ZW1wIDwtIGRhdGEuZnJhbWUocm4gPSByb3duYW1lcyhyZXNfc29ydGVkKSwgcmVzX3NvcnRlZCkgJT4lCiAgbmEub21pdCgpICU+JQogIG11dGF0ZSh1cCA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+IDAsIHBhZGosIDEpKSAjc2V0IHRoZSBwLXZhbHVlIGZvciBkb3duIHJlZ3VsYXRpb25zIHRvIDEKIyBtYWtlIGEgbmFtZWQgdmVjdG9yCnJlc19zb3J0ZWRfdXAgPC0gdGVtcCR1cApuYW1lcyhyZXNfc29ydGVkX3VwKSA8LSB0ZW1wJHJuCnJtKHRlbXApCiMgZnVuY3Rpb24gZm9yIGVucmljaG1lbnQgd2l0aCBwIDAuMDUKdG9wRGlmZkdlbmVzIDwtIGZ1bmN0aW9uKHgpIHsKICByZXR1cm4oeCA8IDAuMDUpCn0KIyMjIHJ1bgp0Zy51cDwtbmV3KCJ0b3BHT2RhdGEiLCNqdXN0IGEgbmFtZQogICAgICAgICAgIGRlc2NyaXB0aW9uPSJyZXNfc29ydGVkX3VwIiwKICAgICAgICAgICBvbnRvbG9neT0iQlAiLAogICAgICAgICAgIGFsbEdlbmVzPXJlc19zb3J0ZWRfdXBbMToxMDBdLCAjbmFtZWQgdmVjdG9yIHdpdGggYWRqLiBwLXZhbHVlcwogICAgICAgICAgIGdlbmVTZWw9dG9wRGlmZkdlbmVzLAogICAgICAgICAgIGFubm90PWFubkZVTi5vcmcsCiAgICAgICAgICAgbm9kZVNpemUgPSAxMCwgI21pbmltdW0gbnVtYmVyIG9mIGdlbmVzIGluIGEgR08gY2F0ZWdvcnkKICAgICAgICAgICBJRD0iRW5zZW1ibCIsCiAgICAgICAgICAgbWFwcGluZz0ib3JnLkhzLmVnLmRiIikKCiMgS29sbW9nb3Jvdi1TbWlybm92IChLUyktdGVzdApyZXN1bHRzLmtzIDwtIHJ1blRlc3QodGcudXAsIGFsZ29yaXRobSA9ICJ3ZWlnaHQwMSIsIHN0YXRpc3RpYyA9ICJrcyIpCnF2YWwgPC0gZGF0YS5mcmFtZShxVmFsID0gcC5hZGp1c3Qoc2NvcmUocmVzdWx0cy5rcyksIG1ldGhvZCA9ICJCSCIpLAogICAgICAgICAgICAgICAgICAgR08uSUQgPSBuYW1lcyhzY29yZShyZXN1bHRzLmtzKSkpCiMgcmVzdWx0cyB0YWJsZQpnb0VucmljaG1lbnQgPC0KICBHZW5UYWJsZSh0Zy51cCwKICAgICAgICAgICBLUyA9IHJlc3VsdHMua3MsCiAgICAgICAgICAgb3JkZXJCeSA9ICJLUyIsCiAgICAgICAgICAgdG9wTm9kZXMgPSAxMCkKZ29FbnJpY2htZW50IDwtIGlubmVyX2pvaW4oZ29FbnJpY2htZW50LCBxdmFsLCBieSA9ICJHTy5JRCIpCmhlYWQoZ29FbnJpY2htZW50KQoKYGBgCgoKIyMjIFJlYWN0b21lCgoiUmVhY3RvbWUgaXMgYSBmcmVlLCBvcGVuLXNvdXJjZSwgY3VyYXRlZCBhbmQgcGVlci1yZXZpZXdlZCBwYXRod2F5IGRhdGFiYXNlLiIgUmVhY3RvbWVQQSBpcyBhIHVzZWZ1bCBwYWNrYWdlIHRoYXQgYWxsb3dzIHlvdSB0byB1c2UgUmVhY3RvbWUgZGF0YWJhc2UgYW5kIHZpc3VhbGl6ZSB5b3VyIHJlc3VsdHMuCgojIyMgRmluZGluZyBzaWduaWZpY2FudCBSZWFjdG9tZSBwYXRod2F5cyBmcm9tIGdlbmUgbGlzdAoKYGBge3J9CmxpYnJhcnkoUmVhY3RvbWVQQSkKCiNZb3UgbmVlZCB0byBjaGVjayB3aGF0IHR5cGUgb2YgZ2VuZSBJRCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIFJlYWN0b21lUEEgYWNjZXB0czogVGhpcyBjYW4gYmUgRU5UUkVaIElELCBFTlNFTUJMIElEIGV0Yy4KCiNIZXJlIHdlIHdpbGwgY29udmVydCBnZW5lIHN5bWJvbHMgKGkuZS4gTHlwbGExKSB0byBFTlRSRVogSUQgKGkuZS4gMTg3NzcpLiBGb3IgdGhpcyB3ZSBuZWVkIHRoZSBmb2xsb3dpbmcgcGFja2FnZXM6CmxpYnJhcnkoQW5ub3RhdGlvbkRiaSkgCgojVGhpcyBleGFtcGxlIGlzIGZyb20gbW91c2UgZGF0YSwgc286CmxpYnJhcnkob3JnLk1tLmVnLmRiKQoKI0hlcmUgd2Ugc2VsZWN0IHRoZSBnZW5lcyB0aGF0IGFyZSB1cHJlZ3VsYXRlZCBpbiBtdXRhbnQgY29tcGFyZWQgdG8gY29udHJvbApyZXNfbXV0YW50X2N0cmxfZ3JlYXRlcjwtcmVzdWx0cyhkZHMuZ2FzdHJvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYXN0PSBjKCJnZW5vdHlwZSIsIktPIiwiV1QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0SHlwb3RoZXNpcyA9ICJncmVhdGVyIikgCgojQWRkIHJvdyBuYW1lcyBhcyBjb2x1bW4gYW5kIG9taXQgTkEKcmVzX211dGFudF9jdHJsX2dyZWF0ZXI8LWRhdGEuZnJhbWUocm49IHJvd25hbWVzKHJlc19tdXRhbnRfY3RybF9ncmVhdGVyKSxyZXNfbXV0YW50X2N0cmxfZ3JlYXRlcikgJT4lIG5hLm9taXQoKQoKI01ha2UgYSBuYW1lZCB2ZWN0b3Igb2YgcC1hZGp1c3RlZCB2YWx1ZXMuIE5hbWVzIGFyZSB0aGUgZ2VuZSBuYW1lcy4KbXV0YW50X3VwIDwtIHJlc19tdXRhbnRfY3RybF9ncmVhdGVyJHBhZGogCm5hbWVzKG11dGFudF91cCkgPC0gcmVzX211dGFudF9jdHJsX2dyZWF0ZXIkcm4KCiNNYWtlIGEgZGF0YSBmcmFtZSB3aXRoIGdlbmUgbmFtZXMgYW5kIGNvcnJlc3BvbmRpbmcgRU5UUkVaIElEcy4KZW5zZ0VudHJlel9tdXRhbnQgPC0gQW5ub3RhdGlvbkRiaTo6c2VsZWN0KG9yZy5NbS5lZy5kYiwga2V5cz1uYW1lcyhtdXRhbnRfdXApLCBjb2x1bW5zPSdFTlNFTUJMSUQnLCBrZXl0eXBlPSdTWU1CT0wnKQoKI01ha2UgYSBkYXRhIGZyYW1lIHdpdGggRU5UUkVaIElEcywgTG9nMkZvbGRDaGFuZ2VzIGFuZCBwLWFkanVzdGVkIHZhbHVlcy4KZGZfbXV0YW50IDwtZW5zZ0VudHJlel9tdXRhbnQgJT4lCiAgZHBseXI6OmlubmVyX2pvaW4ocmVzX211dGFudF9jdHJsX2dyZWF0ZXIsIGJ5PWMoIlNZTUJPTCI9InJuIikpICU+JSAKICBkcGx5cjo6c2VsZWN0KEVOVFJFWklELGxvZzJGb2xkQ2hhbmdlLHBhZGopICU+JSAKICBkcGx5cjo6Z3JvdXBfYnkoRU5UUkVaSUQpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UobGZjPW1lYW4obG9nMkZvbGRDaGFuZ2UpLCBwYWRqPW1pbihwYWRqKSkKCiNNYWtlIGEgbGlzdCBvZiB0aGUgRU5UUkVaIElEcyBvZiB0aGUgZ2VuZXMgd2l0aCBwYWRqIDw9IDAuMS4Kc2c8LXVuaXF1ZSgoZGZfbXV0YW50ICU+JSBkcGx5cjo6ZmlsdGVyKHBhZGo8PTAuMSkpJEVOVFJFWklEKQoKI1NlYXJjaCB0aGUgUmVhY3RvbWUgZGF0YWJhc2UgZm9yIHRoZSBwYXRod2F5cyB3aGljaCBvdXIgc2lnbmlmaWNhbnQgZ2VuZXMgYXJlIGFubm90YXRlZCB0by4gCnhfbXV0YW50X3VwIDwtIGVucmljaFBhdGh3YXkoZ2VuZT1zZywgb3JnYW5pc20gPSAibW91c2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml2ZXJzZT0gdW5pcXVlKGRmX211dGFudCRFTlRSRVpJRCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZj0wLjEsIHBBZGp1c3RNZXRob2Q9IkJIIiwgcmVhZGFibGU9VCkKCiNFeHRyYWN0IHRoZSByZXN1bHRzIGludG8gYSBkYXRhIGZyYW1lLgp4X211dGFudF91cF9kZiA8LSB4X211dGFudF91cEByZXN1bHQKYGBgCgojIyMgVmlzdWFsaXppbmcgUmVhY3RvbWUgcmVzdWx0cyB3aXRoIFJlYWN0b21lUEEKCmBgYHtyfQojWW91IGNhbiBzYXZlIHRoZSBwbG90IGFzIHBuZyBidXQgc2V0IHRoZSByZXNvbHV0aW9uICh3aWR0aHhoZWlnaHQpLgoKcG5nKGZpbGU9IlJlYWN0b21lRG90X011dGFudF9Db250cm9sX1VwLnBuZyIsIHdpZHRoPTE0NDAsIGhlaWdodD0xMjgwKQpkb3RwbG90KHhfbXV0YW50X3VwLCBzaG93Q2F0ZWdvcnk9MzAsIGZvbnQuc2l6ZT0xNSwgbGFiZWxfZm9ybWF0ID0gMTApICsgZ2d0aXRsZSgiTXV0YW50IHZzIENvbnRyb2wgVXByZWd1bGF0ZWQiKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMwLCBmYWNlID0gImJvbGQiKSkKZGV2Lm9mZigpCgojRm9yIHRoZSBuZXh0IG9uZSwgd2UgbmVlZCB0byBhZGQgTG9nMkZvbGRDaGFuZ2VzIHRvby4gTWFrZSBhIG5hbWVkIHZlY3RvciBqdXN0IGxpa2Ugd2UgZGlkIHdpdGggcC1hZGp1c3RlZCB2YWx1ZXMgYmVmb3JlLgpsZmMgPC1kZl9tdXRhbnQkbGZjCm5hbWVzKGxmYyk8LWRmX211dGFudCRFTlRSRVpJRAoKCiNNYWtlIGFuZCBzYXZlIHRoZSBwbG90CnBuZyhmaWxlPSJDTkVUX011dGFudF9Db250cm9sX1VwLnBuZyIsIHdpZHRoPTE0NDAsIGhlaWdodD0xNDQwKQpjbmV0cGxvdCh4X211dGFudF91cCwgc2hvd0NhdGVnb3J5ID0xMCwgZm9sZENoYW5nZT0yXmxmYyxjZXhfbGFiZWxfZ2VuZSA9IDEuMiwgY2V4X2xhYmVsX2NhdGVnb3J5ID0gMS44KSArIGdndGl0bGUoIk11dGFudCB2cyBDb250cm9sIFVwcmVndWxhdGVkIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA0MCwgZmFjZSA9ICJib2xkIikpCmRldi5vZmYoKQpgYGAKCgoKYGBge3J9CnNhdmUoZ3BfdXAsIHRnLnVwLCBmaWxlID0gIi4vZGF0YS9Sb2JqZWN0cy8wNV9lbnJpY2htZW50LlJEYXRhIikKbG9hZCgiLi9kYXRhL1JvYmplY3RzLzA1X2VucmljaG1lbnQuUkRhdGEiKQpgYGAKCg==